import { useRequest } from 'ahooks';
import {
  Button,
  Checkbox,
  Form,
  Icon,
  Input,
  message,
  Modal,
  Radio,
  Row,
  Spin,
  Tabs,
  Tooltip,
} from 'antd';
import React, { useRef, useState } from 'react';
import request from '@/utils/request';
import CodeEditor from '@/components/CodeEditor';
import { serialize } from '@/pages/Transformer/components/SourcePanel/utils';
import DynamicKeyValuePairs from '@/components/DynamicKeyValuePairs';
import { mapFormatToEditorMode } from '../ProcessRun';
import Mapper from '@/pages/Transformer/components/Mapper';
import DynamicHttpHeaders, { clipboardTextHeaderValues } from '@/components/DynamicHttpHeaders';

const formLayout1 = {
  labelCol: {
    sm: { span: 4 },
  },
  wrapperCol: {
    sm: { span: 18 },
  },
};

const formLayout2 = {
  labelCol: {
    sm: { span: 8 },
  },
  wrapperCol: {
    sm: { span: 16 },
  },
};

export const DynamicVariable = ({ value = {}, onChange, treeData }) => {
  const { isConstant = false, path, value: inputValue } = value;
  const [checked, setChecked] = useState(isConstant);
  return (
    <span style={{ display: 'flex', alignItems: 'center' }}>
      {checked ? (
        <Input
          className="margin-right"
          value={inputValue}
          onChange={e => onChange({ isConstant: true, value: e.target.value })}
          placeholder="VALUE"
        />
      ) : (
        <Mapper
          style={{ width: '100%', marginRight: 8 }}
          treeData={treeData}
          value={path}
          onChange={value => onChange({ isConstant: false, path: value })}
        />
      )}
      <Tooltip title="是否常量">
        <Checkbox onChange={e => setChecked(e.target.checked)} checked={checked} />
      </Tooltip>
    </span>
  );
};

function ProcessSetting({ data, visible, form, onCancel }) {
  const { getFieldDecorator, setFieldsValue, getFieldValue, getFieldsValue } = form;
  const { versionId, readOnly = true } = data;
  const [saveLoading, setSaveLoading] = useState(false);
  const [activeTab, setActiveTab] = useState('initMessage');
  const initMsgRef = useRef();
  const [httpHeaders, setHttpHeaders] = useState([]);
  const headersRef = useRef(null);

  const { loading } = useRequest(
    () => {
      if (!versionId) {
        return Promise.resolve({});
      }
      return request.get(`/process/getRunSettings?versionId=${versionId}`);
    },
    {
      onSuccess: data => {
        setFieldsValue({
          ...data,
          processLogOption: data.processLogOption || 'YES',
          processLogContentOption: data.processLogContentOption || 'YES',
          taskLogOption: data.taskLogOption || 'YES',
          taskLogContentOption: data.taskLogContentOption || 'YES',
        });
        const editor = initMsgRef.current;
        if (data.initContentFormat && data.initContent) {
          editor.setMode(mapFormatToEditorMode[data.initContentFormat]);
          editor.setValue(data.initContent);
        }
        setHttpHeaders(data.httpHeaders);
      },
      refreshDeps: [versionId],
    }
  );

  const { data: tree, loading: treeLoading, run: loadTree } = useRequest(
    () => {
      const editor = initMsgRef.current;
      if (!editor.getValue()) {
        return Promise.resolve(null);
      }
      return request.post(`/transform/parseSourceTree`, {
        data: {
          format: editor.getFormat(),
          message: editor.getValue(),
        },
      });
    },
    {
      manual: true,
    }
  );

  const treeData = tree ? serialize([tree]) : [];

  const handleProcessLogOptionChange = e => {
    const { value } = e.target;
    if (value === 'NO') {
      setFieldsValue({
        processLogContentOption: 'NO',
        taskLogOption: 'NO',
        taskLogContentOption: 'NO',
      });
    }
  };

  const handleTaskLogOptionChange = e => {
    const { value } = e.target;
    if (value === 'NO') {
      setFieldsValue({
        taskLogContentOption: 'NO',
      });
    }
  };

  const handleSave = () => {
    const editor = initMsgRef.current;
    setSaveLoading(true);
    request
      .post(`/process/saveRunSettings?versionId=${versionId}`, {
        data: {
          initContent: editor.getValue(),
          initContentFormat: editor.getFormat(),
          ...getFieldsValue(),
          httpHeaders,
        },
      })
      .then(() => {
        message.success('保存成功');
        onCancel();
      })
      .finally(() => {
        setSaveLoading(false);
      });
  };

  const noProcessLogOption = getFieldValue('processLogOption') === 'NO';
  const noTaskLogOption = getFieldValue('taskLogOption') === 'NO';

  const onTabChange = activeKey => {
    if (activeTab === 'initMessage') {
      loadTree();
    }
    setActiveTab(activeKey);
  };

  return (
    <Modal
      width={1000}
      title="运行设置"
      okText="保存"
      onOk={handleSave}
      okButtonProps={{ loading: saveLoading }}
      visible={visible}
      onCancel={onCancel}
      destroyOnCloses
    >
      <Spin spinning={loading}>
        <Form>
          <Tabs activeKey={activeTab} onChange={onTabChange}>
            <Tabs.TabPane tab="初始报文" key="initMessage">
              <CodeEditor ref={initMsgRef} switchable height={481} />
            </Tabs.TabPane>
            <Tabs.TabPane tab="初始请求头" key="initHeaders">
              <DynamicHttpHeaders ref={headersRef} value={httpHeaders} onChange={setHttpHeaders} />
              <Button
                onClick={async () => {
                  try {
                    const headers = await clipboardTextHeaderValues();
                    headersRef.current.resetList(headers);
                  } catch (error) {
                    message.error(error.message);
                  }
                }}
                className="margin-top"
                icon="bg-colors"
                ghost
                type="primary"
              >
                填充Header
              </Button>
            </Tabs.TabPane>
            <Tabs.TabPane tab="业务实例信息" key="instanceInfo">
              <Spin spinning={treeLoading}>
                <Form.Item label="实例ID" {...formLayout1}>
                  {getFieldDecorator('instanceIdPath')(<Mapper treeData={treeData} />)}
                </Form.Item>
                <Form.Item label="轨迹ID" {...formLayout1}>
                  {getFieldDecorator('traceIdPath')(<Mapper treeData={treeData} />)}
                </Form.Item>
                <Form.Item label="分片键" {...formLayout1}>
                  {getFieldDecorator('shardingKeyPath')(<Mapper treeData={treeData} />)}
                </Form.Item>
              </Spin>
            </Tabs.TabPane>
            <Tabs.TabPane tab="流程变量" key="processVariables">
              <Form.Item>
                {getFieldDecorator('processVariables', {
                  initialValue: {},
                })(
                  <DynamicKeyValuePairs
                    layout={{ label: 1, value: 2 }}
                    renderValueComponent={props => (
                      <DynamicVariable treeData={treeData} {...props} />
                    )}
                  />
                )}
              </Form.Item>
            </Tabs.TabPane>
            <Tabs.TabPane tab="日志写入策略" key="logStrategy">
              <Form.Item
                label={
                  <span>
                    TG_PROCESS_LOG 表&nbsp;
                    <Tooltip title="流程日志主表">
                      <Icon type="question-circle-o" />
                    </Tooltip>
                  </span>
                }
                {...formLayout2}
              >
                {getFieldDecorator('processLogOption', {
                  initialValue: 'YES',
                })(
                  <Radio.Group onChange={handleProcessLogOptionChange}>
                    <Radio value="YES">记录</Radio>
                    <Radio value="NO">不记录</Radio>
                    <Radio value="ONLY_ERROR">仅当异常时记录</Radio>
                  </Radio.Group>
                )}
              </Form.Item>

              <Form.Item
                label={
                  <span>
                    TG_PROCESS_LOG_CONTENT 表&nbsp;
                    <Tooltip title="流程请求响应报文表">
                      <Icon type="question-circle-o" />
                    </Tooltip>
                  </span>
                }
                {...formLayout2}
              >
                {getFieldDecorator('processLogContentOption', {
                  initialValue: 'YES',
                })(
                  <Radio.Group>
                    <Radio disabled={noProcessLogOption} value="YES">
                      记录
                    </Radio>
                    <Radio value="NO">不记录</Radio>
                    <Radio disabled={noProcessLogOption} value="ONLY_ERROR">
                      仅当异常时记录
                    </Radio>
                  </Radio.Group>
                )}
              </Form.Item>

              <Form.Item
                label={
                  <span>
                    TG_TASK_LOG 表&nbsp;
                    <Tooltip title="流程环节主表">
                      <Icon type="question-circle-o" />
                    </Tooltip>
                  </span>
                }
                {...formLayout2}
              >
                {getFieldDecorator('taskLogOption', {
                  initialValue: 'YES',
                })(
                  <Radio.Group onChange={handleTaskLogOptionChange}>
                    <Radio disabled={noProcessLogOption} value="YES">
                      记录
                    </Radio>
                    <Radio value="NO">不记录</Radio>
                    <Radio disabled={noProcessLogOption} value="ONLY_ERROR">
                      仅当异常时记录
                    </Radio>
                  </Radio.Group>
                )}
              </Form.Item>
              <Form.Item
                label={
                  <span>
                    TG_TASK_LOG_CONTENT 表&nbsp;
                    <Tooltip title="流程环节详情表（大报文表）">
                      <Icon type="question-circle-o" />
                    </Tooltip>
                  </span>
                }
                {...formLayout2}
              >
                {getFieldDecorator('taskLogContentOption', {
                  initialValue: 'YES',
                })(
                  <Radio.Group>
                    <Radio disabled={noProcessLogOption || noTaskLogOption} value="YES">
                      记录
                    </Radio>
                    <Radio value="NO">不记录</Radio>
                    <Radio disabled={noProcessLogOption || noTaskLogOption} value="ONLY_ERROR">
                      仅当异常时记录
                    </Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Tabs.TabPane>
          </Tabs>
        </Form>
      </Spin>
    </Modal>
  );
}

export default Form.create()(ProcessSetting);
